package com.xy.biz.xd.domain.strategy.impl;

import com.xy.biz.base.client.DictClient;
import com.xy.biz.base.domain.req.ListDictItemRequest;
import com.xy.biz.base.domain.resp.ListDictItemResponse;
import com.xy.biz.fd.domain.utils.DocumentPropertyUtils;
import com.xy.biz.uc.client.UserClient;
import com.xy.biz.uc.domain.dto.UserDTO;
import com.xy.biz.uc.domain.req.GetUserRequest;
import com.xy.biz.xd.domain.bo.DocumentFlowConstants;
import com.xy.biz.xd.domain.constant.ExcelModelConstant;
import com.xy.biz.xd.domain.query.DocumentFlowHandleQuery;
import com.xy.biz.xd.domain.query.DocumentFlowQuery;
import com.xy.biz.xd.domain.req.GenerateDocumentRequest;
import com.xy.biz.xd.domain.req.GetDocumentFlowSimpleHandlesRequest;
import com.xy.biz.xd.domain.resp.GetDocumentFlowHandleResponse;
import com.xy.biz.xd.domain.resp.GetDocumentFlowResponse;
import com.xy.biz.xd.domain.strategy.ExcelModelStrategy;
import com.xy.biz.xd.domain.strategy.model.CellMode;
import com.xy.biz.xd.service.DocumentFlowHandleService;
import com.xy.biz.xd.service.DocumentFlowService;
import com.xy.lang.util.ResultUtils;
import com.xy.tool.minio.util.LedgerTemplateUtils;
import com.xy.tool.report.excel.MultiSheetExcelTemplate;
import com.xy.tool.report.view.Table;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFCellStyle;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

import static com.xy.biz.xd.domain.constant.ExcelModelConstant.USE_AND_CHANGE;

/**
 * @author Greekn Zhang
 * @date 2021/7/1 14:09
 * @description
 */
@Service(ExcelModelStrategy.EXCEL_MOD + USE_AND_CHANGE)
public class ExcelUserAndChangeLedger implements ExcelModelStrategy {

    @Autowired
    private DocumentFlowService documentFlowService;
    @Autowired
    private DocumentFlowHandleService documentFlowHandleService;
    @Autowired
    private UserClient userClient;
    @Autowired
    private DictClient dictClient;
    @Autowired
    private LedgerTemplateUtils ledgerTemplateUtils;
    private static final String LIST_TEMPLATE = "DocumentUseAndChangeTemplate.xlsx";
    private static final String ONE_TEMPLATE = "OneDocumentUseAndChangeTemplate.xlsx";

    /**
     * 根据模板类型创建表格
     */
    @Override
    public SXSSFWorkbook generate(GenerateDocumentRequest request) throws IOException {
//        if (request.getPageSize() == null || request.getPageIndex() == null) {
//            request.setPageIndex(0);
//            request.setPageSize(Integer.MAX_VALUE);
//        }
        //获取所有QA参与的流程
        List<GetDocumentFlowResponse> docs = documentFlowService.listLedgerData(DocumentFlowQuery.builder().documentFlowId(request.getFlowId()).build()).getRows();
        if (request.getFlowId() != null) {
            return generateOne(request, docs);
        }
        //1、加载模板流数据
        InputStream inputStream = ledgerTemplateUtils.getUrl(LIST_TEMPLATE);
        //2.根据文件流，加载指定的工作簿
        XSSFWorkbook wb = new XSSFWorkbook(inputStream);
        SXSSFWorkbook workbook = new SXSSFWorkbook(wb);
        //3.读取工作表
        Sheet sheet = wb.getSheetAt(0);
        //4.设置表头
        Cell codeCell = sheet.getRow(0).getCell(0);
        codeCell.setCellValue(codeCell.getStringCellValue() + request.getDocumentNumber());
        Cell headerCell = sheet.getRow(1).getCell(0);
        headerCell.setCellValue(request.getDocumentHeader());
        Cell nameCell = sheet.getRow(2).getCell(0);
        nameCell.setCellValue(request.getDocumentName());
        //5.构造每行和单元格数据
        AtomicInteger datasAi = new AtomicInteger(4);
        Cell cell = null;
        CellStyle cellCenter = workbook.createCellStyle();
        CellStyle cellLeft = workbook.createCellStyle();
        cellCenter.setAlignment(HorizontalAlignment.CENTER);
        cellCenter.setVerticalAlignment(VerticalAlignment.CENTER);
        cellCenter.setBorderBottom(BorderStyle.THIN);
        cellCenter.setBorderLeft(BorderStyle.THIN);
        cellCenter.setBorderRight(BorderStyle.THIN);
        cellCenter.setBorderTop(BorderStyle.THIN);
        cellLeft.setAlignment(HorizontalAlignment.LEFT);
        cellLeft.setVerticalAlignment(VerticalAlignment.CENTER);
        cellLeft.setBorderBottom(BorderStyle.THIN);
        cellLeft.setBorderLeft(BorderStyle.THIN);
        cellLeft.setBorderRight(BorderStyle.THIN);
        cellLeft.setBorderTop(BorderStyle.THIN);
        docs.sort(Comparator.comparing(GetDocumentFlowResponse::getDocumentCode));
        Map<String, String> documentPropertyMap = ResultUtils.get(dictClient.listDictItem(ListDictItemRequest.builder().dictGroupCode("document_category").build())).stream().collect(Collectors.toMap(ListDictItemResponse::getDictCode, ListDictItemResponse::getDictValue));
        for (int i = 0; i < docs.size(); i++) {
            GetDocumentFlowResponse d = docs.get(i);
            Row dataRow = sheet.createRow(datasAi.getAndIncrement());
            //编号
            cell = dataRow.createCell(0);
            cell.setCellValue(1 + i);
            cell.setCellStyle(cellCenter);
            //文件类型
            cell = dataRow.createCell(1);
            cell.setCellValue(documentPropertyMap.get(d.getDocumentProperty()));
            cell.setCellStyle(cellCenter);
            //文件名称
            cell = dataRow.createCell(2);
            cell.setCellValue(d.getDocumentName());
            cell.setCellStyle(cellLeft);
            //文件编号
            cell = dataRow.createCell(3);
            cell.setCellValue(d.getDocumentCode());
            cell.setCellStyle(cellCenter);
            //版本号
            cell = dataRow.createCell(4);
            cell.setCellValue(d.getDocumentVersion());
            cell.setCellStyle(cellCenter);
            //所属部门
            cell = dataRow.createCell(5);
            cell.setCellValue(d.getCreateUserGroupName());
            cell.setCellStyle(cellCenter);
            //申请日期
            cell = dataRow.createCell(6);
            DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd");
            cell.setCellValue(d.getCreateTime().format(df));
            cell.setCellStyle(cellCenter);
            //申请人员
            cell = dataRow.createCell(7);
            cell.setCellValue(d.getCreateUserName());
            cell.setCellStyle(cellCenter);
            //申请编号
            cell = dataRow.createCell(8);
            cell.setCellValue("暂无");
            cell.setCellStyle(cellCenter);
            //申请类别
            cell = dataRow.createCell(9);
            cell.setCellValue(d.getFlowTypeName());
            cell.setCellStyle(cellCenter);
            //申请原因
            cell = dataRow.createCell(10);
            cell.setCellValue(d.getReason());
            cell.setCellStyle(cellLeft);
            //进展
            cell = dataRow.createCell(11);
            cell.setCellValue(d.getPhaseName());
            cell.setCellStyle(cellCenter);
            //备注
            cell = dataRow.createCell(12);
            cell.setCellValue("无");
            cell.setCellStyle(cellLeft);
        }
        return workbook;
    }

    /**
     * @author Greekn Zhang
     * @date 2021/7/12 17:27
     * @param request
     * @return org.apache.poi.xssf.streaming.SXSSFWorkbook
     * @description 单条打印
     */
    private SXSSFWorkbook generateOne(GenerateDocumentRequest request, List<GetDocumentFlowResponse> docs) throws IOException {
        if (CollectionUtils.isEmpty(docs)) {
            return null;
        }
        List<GetDocumentFlowResponse> collect = docs.stream().filter(d -> d.getDocumentFlowId().equals(request.getFlowId())).collect(Collectors.toList());
        GetDocumentFlowResponse response = collect.get(0);
        List<GetDocumentFlowHandleResponse> getDocumentFlowHandleResponses = documentFlowHandleService.listDocumentFlowNodesHandle(GetDocumentFlowSimpleHandlesRequest.builder().documentFlowId(response.getDocumentFlowId()).build());
        //1、加载模板流数据
        InputStream inputStream = ledgerTemplateUtils.getUrl(ONE_TEMPLATE);
        //FileInputStream fis = new FileInputStream(resource.getFile());
        //2.根据文件流，加载指定的工作簿
        //XSSFWorkbook wb = new XSSFWorkbook(fis);
        XSSFWorkbook wb = new XSSFWorkbook(inputStream);
        SXSSFWorkbook workbook = new SXSSFWorkbook(wb);
        //3.读取工作表
        Sheet sheet = wb.getSheetAt(0);
        //4.设置表头
        Cell codeCell = sheet.getRow(0).getCell(0);
        codeCell.setCellValue(codeCell.getStringCellValue() + request.getDocumentNumber());
        Cell headerCell = sheet.getRow(1).getCell(0);
        headerCell.setCellValue(request.getDocumentHeader());
        Cell nameCell = sheet.getRow(2).getCell(0);
        nameCell.setCellValue(request.getDocumentName());
        Cell applicationNumCell = sheet.getRow(3).getCell(3);
        applicationNumCell.setCellValue(response.getDocumentCode());
        Cell applicationTypeCell = sheet.getRow(4).getCell(1);
        applicationTypeCell.setCellValue(DocumentFlowConstants.getFlowName(response.getFlowType()));
        Cell documentNameCell = sheet.getRow(6).getCell(0);
        documentNameCell.setCellValue(response.getDocumentName());
        Cell documentCodeCell = sheet.getRow(6).getCell(2);
        documentCodeCell.setCellValue(response.getDocumentCode());
        Cell documentVersionCell = sheet.getRow(6).getCell(4);
        documentVersionCell.setCellValue(response.getDocumentVersion());
        Cell applyReasonCell = sheet.getRow(9).getCell(0);
        applyReasonCell.setCellValue(applyReasonCell.getStringCellValue() + response.getReason());
        //申请人部门
        Cell applyUserGroupNameCell = sheet.getRow(10).getCell(0);
        UserDTO userDTO = ResultUtils.get(userClient.getUser(GetUserRequest.builder().userId(response.getCreateUserId()).withUserGroup(true).build()));
        applyUserGroupNameCell.setCellValue(applyUserGroupNameCell.getStringCellValue() + userDTO.getUserGroup().getName());
        //申请人名称
        Cell applyCell = sheet.getRow(10).getCell(2);
        applyCell.setCellValue(applyCell.getStringCellValue() + response.getCreateUserName());
        //申请日期
        Cell applyDateCell = sheet.getRow(10).getCell(3);
        DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        applyDateCell.setCellValue(applyDateCell.getStringCellValue() + response.getCreateTime().format(df));
        //获取上传阶段的信息
        List<GetDocumentFlowHandleResponse> adminAudit = getDocumentFlowHandleResponses.stream().filter(d -> d.getPhase().equals(DocumentFlowConstants.PHASE_UPLOAD)).collect(Collectors.toList());
        if (!CollectionUtils.isEmpty(adminAudit)) {
            adminAudit.sort((m1, m2) -> m2.getCreateTime().compareTo(m1.getCreateTime()));
            //质保专员意见
            Cell qaOpinion = sheet.getRow(11).getCell(0);
            qaOpinion.setCellValue(qaOpinion.getStringCellValue() + adminAudit.get(0).getOpinion());
            Cell qaSignature = sheet.getRow(12).getCell(0);
            qaSignature.setCellValue(qaSignature.getStringCellValue() + adminAudit.get(0).getHandleUserName() + "(" + DocumentFlowConstants.getResult(adminAudit.get(0).getResult()) + ")");
            Cell qaSignatureDate = sheet.getRow(12).getCell(3);
            qaSignatureDate.setCellValue(qaSignatureDate.getStringCellValue() + adminAudit.get(0).getCreateTime().format(df));
        }
        //获取文件评审阶段的信息
        List<GetDocumentFlowHandleResponse> review = getDocumentFlowHandleResponses.stream().filter(d -> d.getPhase().equals(DocumentFlowConstants.PHASE_REVIEW)).collect(Collectors.toList());
        if (!CollectionUtils.isEmpty(review)) {
            //相关部门负责人评审意见
            review.sort((m1, m2) -> m2.getCreateTime().compareTo(m1.getCreateTime()));
            Cell managerOpinion = sheet.getRow(13).getCell(0);
            managerOpinion.setCellValue(managerOpinion.getStringCellValue() + review.get(0).getOpinion());
            Cell managerSignature = sheet.getRow(14).getCell(0);
            managerSignature.setCellValue(managerSignature.getStringCellValue() + review.get(0).getHandleUserName() + "(" + DocumentFlowConstants.getResult(review.get(0).getResult()) + ")");
            Cell managerSignatureDate = sheet.getRow(14).getCell(3);
            managerSignatureDate.setCellValue(managerSignatureDate.getStringCellValue() + review.get(0).getCreateTime().format(df));
        }
        //获取文件初步审核阶段的信息
        List<GetDocumentFlowHandleResponse> formatAudit = getDocumentFlowHandleResponses.stream().filter(d -> d.getPhase().equals(DocumentFlowConstants.PHASE_FORMAT_AUDIT)).collect(Collectors.toList());
        //质保专员/部门负责人初步审核意见
        if (!CollectionUtils.isEmpty(formatAudit)) {
            formatAudit.sort((m1, m2) -> m2.getCreateTime().compareTo(m1.getCreateTime()));
            Cell managerOpinion = sheet.getRow(15).getCell(0);
            managerOpinion.setCellValue(managerOpinion.getStringCellValue() + formatAudit.get(0).getOpinion());
            Cell managerSignature = sheet.getRow(16).getCell(0);
            managerSignature.setCellValue(managerSignature.getStringCellValue() + formatAudit.get(0).getHandleUserName() + "(" + DocumentFlowConstants.getResult(formatAudit.get(0).getResult()) + ")");
            Cell managerSignatureDate = sheet.getRow(16).getCell(3);
            managerSignatureDate.setCellValue(managerSignatureDate.getStringCellValue() + formatAudit.get(0).getCreateTime().format(df));
        }
        //获取总监文件审核/审批阶段的信息
        List<GetDocumentFlowHandleResponse> audit = getDocumentFlowHandleResponses.stream().filter(d -> d.getPhase().equals(DocumentFlowConstants.PHASE_CONTENT_AUDIT)).collect(Collectors.toList());
        //各总监审核/审批意见
        if (!CollectionUtils.isEmpty(audit)) {
            audit.sort((m1, m2) -> m2.getCreateTime().compareTo(m1.getCreateTime()));
            Cell managerOpinion = sheet.getRow(17).getCell(0);
            managerOpinion.setCellValue(managerOpinion.getStringCellValue() + audit.get(0).getOpinion());
            Cell managerSignature = sheet.getRow(18).getCell(0);
            managerSignature.setCellValue(managerSignature.getStringCellValue() + audit.get(0).getHandleUserName() + "(" + DocumentFlowConstants.getResult(audit.get(0).getResult()) + ")");
            Cell managerSignatureDate = sheet.getRow(18).getCell(3);
            managerSignatureDate.setCellValue(managerSignatureDate.getStringCellValue() + audit.get(0).getCreateTime().format(df));
        }
        //管理者代表审核/审批意见
        List<GetDocumentFlowHandleResponse> approve = getDocumentFlowHandleResponses.stream().filter(d -> d.getPhase().equals(DocumentFlowConstants.PHASE_APPROVAL)).collect(Collectors.toList());
        if (!CollectionUtils.isEmpty(approve)) {
            Integer levelNum = 0;// TODO DocumentPropertyUtils.getLevelNum(DocumentCodeFormatValidationUtils.getDocumentProperty(response.getDocumentCode()));
            approve.sort((m1, m2) -> m2.getCreateTime().compareTo(m1.getCreateTime()));
            if (levelNum == 1) {
                Cell managerOpinion = sheet.getRow(19).getCell(0);
                managerOpinion.setCellValue("总经理审核/审批意见：" + approve.get(0).getOpinion());
                Cell managerSignature = sheet.getRow(20).getCell(0);
                managerSignature.setCellValue("总经理签字：" + approve.get(0).getHandleUserName() + "(" + DocumentFlowConstants.getResult(approve.get(0).getResult()) + ")");
                Cell managerSignatureDate = sheet.getRow(20).getCell(3);
                managerSignatureDate.setCellValue(managerSignatureDate.getStringCellValue() + approve.get(0).getCreateTime().format(df));
            } else {
                Cell managerOpinion = sheet.getRow(19).getCell(0);
                managerOpinion.setCellValue(managerOpinion.getStringCellValue() + approve.get(0).getOpinion());
                Cell managerSignature = sheet.getRow(20).getCell(0);
                managerSignature.setCellValue(managerSignature.getStringCellValue() + approve.get(0).getHandleUserName() + "(" + DocumentFlowConstants.getResult(approve.get(0).getResult()) + ")");
                Cell managerSignatureDate = sheet.getRow(20).getCell(3);
                managerSignatureDate.setCellValue(managerSignatureDate.getStringCellValue() + approve.get(0).getCreateTime().format(df));
            }
        }
        return workbook;
    }
    /**
     * 根据模板类型创建表格
     *//*
    @Override
    public SXSSFWorkbook generate(GenerateDocumentRequest request) {
        Table table = new Table();
        table.setName(ExcelModelConstant.getModelName(USE_AND_CHANGE));
        List<Row> headerList = table.getHeaderList();
        Row r1 = new Row();
        //拼接页眉编号
        Cell headerCell1 = new Cell();
        headerCell1.setValue("记录编号：" + request.getDocumentNumber());
        headerCell1.setSpan(13);
        headerCell1.setHorizontalAlignment(TextAlignment.Left);
        Style headerStyle1 = new Style();
        headerStyle1.setFontSize((short) 9);
        headerCell1.setStyle(headerStyle1);
        r1.addCell(headerCell1);
        Row r2 = new Row();
        //拼接页眉
        Cell headerCell2 = new Cell();
        headerCell2.setValue(request.getDocumentHeader());
        headerCell2.setSpan(13);
        headerCell2.setHorizontalAlignment(TextAlignment.Center);
        r2.addCell(headerCell2);
        Row r3 = new Row();
        //拼接页眉编号
        Cell headerCell3 = new Cell();
        headerCell3.setValue(request.getDocumentName());
        headerCell3.setSpan(13);
        headerCell3.setHorizontalAlignment(TextAlignment.Center);
        Style headerStyle3 = new Style();
        headerStyle3.setFontSize((short) 13);
        headerStyle3.setBold(true);
        headerCell3.setStyle(headerStyle3);
        r3.addCell(headerCell3);
        headerList.add(r1);
        headerList.add(r2);
        headerList.add(r3);
        Row row = table.createRow();
        row.addCell(CellMode.genCell(CellMode.NUMBER));
        row.addCell(CellMode.genCell(CellMode.DOCUMENT_TYPE));
        row.addCell(CellMode.genCell(CellMode.DOCUMENT_NAME));
        row.addCell(CellMode.genCell(CellMode.DOCUMENT_CODE));
        row.addCell(CellMode.genCell(CellMode.DOCUMENT_VERSION));
        row.addCell(CellMode.genCell(CellMode.BELONG_TO_GROUP));
        row.addCell(CellMode.genCell(CellMode.APPLY_DATE));
        row.addCell(CellMode.genCell(CellMode.APPLY_USER));
        row.addCell(CellMode.genCell(CellMode.APPLY_CODE));
        row.addCell(CellMode.genCell(CellMode.APPLY_TYPE));
        row.addCell(CellMode.genCell(CellMode.APPLY_REASON));
        row.addCell(CellMode.genCell(CellMode.PHASE));
        row.addCell(CellMode.genCell(CellMode.COMMENT));
        //获取所有QA参与的流程
        DocumentFlowQuery documentFlowQuery = new DocumentFlowQuery(request.getPageIndex(), request.getPageSize());
        documentFlowQuery.setDocumentFlowId(request.getFlowId());
        List<GetDocumentFlowResponse> docs = documentFlowService.listLedgerData(documentFlowQuery).getRows();
        for (int i = 0; i < docs.size(); i++) {
            Row r = table.createRow();
            r.addCell(CellMode.genCell(String.valueOf(i + 1)));
            r.addCell(CellMode.genCell(docs.get(i).getDocumentPropertyName()));
            r.addCell(CellMode.genCell(docs.get(i).getDocumentName()));
            r.addCell(CellMode.genCell(docs.get(i).getDocumentCode()));
            r.addCell(CellMode.genCell(docs.get(i).getDocumentVersion()));
            r.addCell(CellMode.genCell(docs.get(i).getCreateUserGroupName()));
            r.addCell(CellMode.genCell(String.valueOf(docs.get(i).getCreateTime())));
            r.addCell(CellMode.genCell(docs.get(i).getCreateUserName()));
            r.addCell(CellMode.genCell("暂无"));
            r.addCell(CellMode.genCell(docs.get(i).getFlowTypeName()));
            r.addCell(CellMode.genCell(docs.get(i).getReason()));
            r.addCell(CellMode.genCell(docs.get(i).getPhaseName()));
            r.addCell(CellMode.genCell("无"));
        }
        MultiSheetExcelTemplate sheetExcelTemplate = new MultiSheetExcelTemplate();
        List<Table> tables = new ArrayList<>();
        tables.add(table);
        SXSSFWorkbook workbook = sheetExcelTemplate.create(tables, null);
        return workbook;
    }*/
}
